/*

    @singleton
    class C {
        public name = 'foo';
    }
    @singleton
    class D extends C {
    }

    console.log(singleton.get(C).name); // 应该输出 'foo'
    singleton.get(C).name = 'bar';
    console.log(singleton.get(C).name); // 应该输出 'bar'
    console.log(singleton.get(D).name); // 应该输出 'foo'
    
 */

export function singleton<T>(target: new () => T) {
    let instance: T = null;
    Object.defineProperty(target, 'getInstance', {
        value: () => {
            return instance || (instance = new target());
        },
    });
    return target;
};

export namespace singleton {
    export function get<T>(constructor: new (...args: any[]) => T): T {
        return (constructor as any).getInstance();
    }
}